package main

import (
	"context"
	"errors"
	"fmt"
	"golang.org/x/sync/errgroup"
	"net/http"
	"os"
	"os/signal"
	"syscall"
)

func main() {
	g, ctx := errgroup.WithContext(context.Background())

	mux := http.NewServeMux()
	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("hello world"))
	})

	shutDownChan := make(chan struct{}, 1)

	mux.HandleFunc("/shutdown", func(w http.ResponseWriter, r *http.Request) {
		shutDownChan <- struct{}{}
	})

	server := &http.Server{
		Addr:    ":8080",
		Handler: mux,
	}

	g.Go(func() error {
		return server.ListenAndServe()
	})

	// 监听退出事件，关闭服务器
	g.Go(func() error {
		select {
		case <-shutDownChan:
			fmt.Println("shutdown server")
		case <-ctx.Done():
			fmt.Println("shutdown routine receive context done")
		}
		// 关闭server
		server.Shutdown(context.Background())
		return ctx.Err()
	})

	// 监听退出信号
	g.Go(func() error {
		sigChan := make(chan os.Signal)
		signal.Notify(sigChan, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
		select {
		case <-sigChan:
			fmt.Println("receive exit signal")
		case <-ctx.Done():
			fmt.Println("sig routine receive context done")
		}
		return errors.New("receive exit signal")
	})

	g.Wait()
	fmt.Println("server exit")
}
